package com.wms.tool;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Created by guoweijie on 2016/6/9.
 */
public class JsonUtil {
    static private Logger logger = LoggerFactory.getLogger(JsonUtil.class);

    private  static final  char ListBegin = '[';
    private  static final  char ListEnd = ']';
    private  static final char mapBegin = '{';
    private  static final  char mapEnd = '}';


    public static String  getJsonString(JSONObject jsonObject, String path) {
        try {
            if (null == jsonObject || "".equals(jsonObject)) {
                return null;
            }
            if (null == path || "".equals(path)) {
                return null;
            }
            String myJson = String.valueOf(jsonObject);
            CopyOnWriteArrayList<Object> pathValue = getPathValue(path);
            //判断参数只有1位并且是Object 则返回第一层JSONObject
            if (pathValue.size() == 1 && pathValue.get(0).equals("Object")) {
                return myJson;
            } else if (pathValue.size() == 1) {
                //判断参数只有1位,从第一层JSONObject下get
                return String.valueOf(jsonObject.get(String.valueOf(pathValue.get(0))));
            } else if (pathValue.size() > 1) {

                //判断参数有两位及以上则使用循环，循环判断是获取JSONObject 或JSONArray 或key
                for (int x = 0; x <= pathValue.size() - 1; x++) {
                    //循环获取每次参数
                    String value = String.valueOf(pathValue.get(x)).trim();
                    int jsonObjectBegin = 0, jsonObjectEnd = 0, jsonArrayBegin = 0, jsonArrayEnd = 0;
                    //如果参数中有包含"{"和 "}" 则 获取 "{""}"的位置

                    if (value.contains("}") && value.contains("{")) {
                        jsonObjectBegin = value.indexOf(mapBegin);
                        jsonObjectEnd = value.indexOf(mapEnd);
                    }
                    //如果参数中有包含"["和 "]" 则 获取 "[""]"的位置
                    if (value.contains("]") && value.contains("[")) {
                        jsonArrayBegin = value.indexOf(ListBegin);
                        jsonArrayEnd = value.indexOf(ListEnd);
                    }
                    //"{" "}" "[" "]"的位置 都为0 相当于是最后一级的Key
                    if (jsonObjectBegin == 0 && jsonObjectEnd == 0 && jsonArrayBegin == 0 && jsonArrayEnd == 0) {
                        myJson = String.valueOf(new JSONObject(myJson).get(value)).trim();
                    } else if (jsonObjectEnd - jsonObjectBegin == 1) {
                        //"}" - "{"  =1 说明该参数是JSONObject类型的
                        myJson = String.valueOf(new JSONObject(myJson).getJSONObject(value.replace("{", "").replace("}", ""))).trim();
                    } else if (jsonArrayEnd - jsonArrayBegin == 1) {
                        //"]" - "[" =1 说明该参数是JSONArray类型的
                        JSONArray jsonArray = new JSONObject(myJson).getJSONArray(value.replace("[", "").replace("]", "").trim());
                        if (jsonArray.length() > 1) {
                            throw new JSONException("JSONArray 中JSONObject 不唯一，建议使用getJsonArray 方法");
                        } else {
                            myJson = String.valueOf(jsonArray.getJSONObject(0).get(String.valueOf(pathValue.get(x + 1)))).trim();
                            return myJson;
                        }
                    }
                }
            }
            logger.debug("myjson="+myJson);
            return myJson;
        }catch (JSONException e){
        logger.error(e.toString());
        throw new JSONException(jsonObject+"没有该字段："+path);
    }
    }

    public static ArrayList<String> getJsonArray(JSONObject jsonObject, String path){
        try {
            if (null == jsonObject || "".equals(jsonObject)) {
                return null;
            }
            if (null == path || "".equals(path)) {
                return null;
            }
            ArrayList<String> arrayList = new ArrayList<>();
            ArrayList<String> dataList = new ArrayList<String>();
            String myJson = String.valueOf(jsonObject);
            CopyOnWriteArrayList<Object> pathValue = getPathValue(path);
            //判断参数只有1位并且是Object 则返回第一层JSONObject
            if (pathValue.size() > 0) {
                //判断参数有两位及以上则使用循环，循环判断是获取JSONObject 或JSONArray 或key
                //logger.debug("pathValue={}",pathValue);
                for (int x = 0; x <= pathValue.size() - 1; x++) {
                    //循环获取每次参数
                    //logger.debug("pathValue={}",pathValue.get(x));
                    String value = String.valueOf(pathValue.get(x)).trim();
                    int jsonObjectBegin = 0, jsonObjectEnd = 0, jsonArrayBegin = 0, jsonArrayEnd = 0;
                    //如果参数中有包含"{"和 "}" 则 获取 "{""}"的位置
                    if (value.indexOf(mapBegin) != -1 && value.indexOf(mapEnd) != -1) {
                        jsonObjectBegin = value.indexOf(mapBegin);
                        jsonObjectEnd = value.indexOf(mapEnd);
                    }
                    //如果参数中有包含"["和 "]" 则 获取 "[""]"的位置
                    if (value.indexOf(ListBegin) != -1 && value.indexOf(ListEnd) != -1) {
                        jsonArrayBegin = value.indexOf(ListBegin);
                        jsonArrayEnd = value.indexOf(ListEnd);
                    }
                    //logger.debug("myjson={}",myJson);
                    if (jsonObjectBegin == 0 && jsonObjectEnd == 0 && jsonArrayBegin == 0 && jsonArrayEnd == 0) {
                        myJson = String.valueOf(new JSONObject(myJson).get(value)).trim();
                        dataList.add(myJson);
                        return dataList;
                    } else if (jsonObjectEnd - jsonObjectBegin == 1) {
                        //"}" - "{"  =1 说明该参数是JSONObject类型的
                        myJson = String.valueOf(new JSONObject(myJson).getJSONObject(value.replace("{", "").replace("}", ""))).trim();
                    } else if (jsonArrayEnd - jsonArrayBegin == 1) {
                        //"]" - "[" =1 说明该参数是JSONArray类型的
                        JSONArray jsonArray = new JSONObject(myJson).getJSONArray(value.replace("[", "").replace("]", "").trim());

                        for (int z = 0; z < jsonArray.length(); z++) {
                            String newPath = "";
                            //logger.debug("jsonArray.length()={}",jsonArray.length());
                            JSONObject jsonObject1 = jsonArray.getJSONObject(z);
                            //logger.debug("jsonObject1={}",jsonObject1);
                            //将剩余的参数重新组织
                            int number;
                            number = pathValue.size() - x;
                            //logger.debug("x={}",x);
                            //logger.debug("number={}",number);
                            for (int m = 1; m < number; m++) {
                                //获取pathValue剩余的参数
                                String data = String.valueOf(pathValue.get(x + m));
                                if ("".equals(newPath)) {
                                    newPath = data.trim();
                                } else {
                                    newPath = newPath.concat(".").concat(data).trim();
                                }

                            }
                            //logger.debug("newPath={}",newPath);
                            ArrayList<String> newList;
                            if (!"".equals(newPath)) {
                                newList = getJsonArray(jsonObject1, newPath);
                                //logger.debug("newList={}", newList);
                                arrayList.addAll(newList);
                            } else {
                                newList = getJsonArray(jsonObject1, String.valueOf(pathValue.get(x + 1)));
                                //logger.debug("newList={}", newList);
                                arrayList.addAll(newList);
                            }

                        }
                        return arrayList;
                    } else if (jsonArrayEnd - jsonArrayBegin > 1) {
                        //如果"]" - "[" >1 说明有指定的JSONObject，取数字，获取指定的JSONObject
                        String newPath = "";
                        int number = Integer.parseInt(value.substring(jsonArrayBegin + 1, jsonArrayEnd));
                        JSONObject jsonObject2 = new JSONObject(myJson).getJSONArray(value.replace("[", "").replace("]", "").replace(String.valueOf(number), "").trim()).getJSONObject(number);
                        for (int m = x; m <= pathValue.size() - x - 1; m++) {
                            String data = String.valueOf(pathValue.get(m + 1));
                            if ("".equals(newPath)) {
                                newPath = data.trim();
                            } else {
                                newPath = newPath.concat(".").concat(data).trim();
                            }
                        }
                        return getJsonArray(jsonObject2, newPath);
                    }

                }
            }
            return dataList;
        }catch (JSONException e){
            logger.error(e.toString());
            throw new JSONException(jsonObject+"没有该字段："+path);
        }
    }

    /**
     * 分离参数
     * @param path
     * @return
     */
    private static CopyOnWriteArrayList<Object> getPathValue(String path){
        CopyOnWriteArrayList<Object> dataList = new CopyOnWriteArrayList<>();
        if (path.contains(".")){
            String[] dataString = path.split("\\.");
            for (String a:dataString){
                dataList.add(a);
            }
            return dataList;
        }else {
            dataList.add(path);
            return dataList;
        }
    }

    public static ConcurrentHashMap<String, String> jsonToMap(String jsonStr) throws Exception {
        JSONObject jsonObj = new JSONObject(jsonStr);
        Iterator<String> nameItr = jsonObj.keys();
        String name;
        ConcurrentHashMap<String, String> outMap = new ConcurrentHashMap<String, String>();
        while (nameItr.hasNext()) {
            name = nameItr.next();
            outMap.put(name, String.valueOf(jsonObj.get(name)));
        }
        return outMap;
    }

    public String getKeys(JSONObject test) throws JSONException {
        String result = null;
        Iterator keys = test.keys();
        while(keys.hasNext()){
            try{
                String key = keys.next().toString();
                String value = test.optString(key);
                int i = testIsArrayORObject(value);
                if(result == null || result.equals("")){
                    if(i == 0){
                        result = key + ",";
                        //logger.debug("i=0 | key="+key+"| result="+result);
                    }else if( i == 1){
                        result = key + ",";
                        //logger.debug("i=1 | key="+key+"| result="+result);
                        result = getKeys(new JSONObject(value))+",";
                    }else if( i == 2){
                        result = key + ",";
                        //logger.debug("i=2 | key="+key+"| result="+result);
                        JSONArray arrays = new JSONArray(value);
                        for(int k =0;k<arrays.length();k++){
                            JSONObject array = new JSONObject(arrays.get(k));
                            result = getKeys(array) + ",";
                        }
                    }
                }else{
                    if(i == 0){
                        result = result + key + ",";
                        //logger.debug("i=0 | key="+key+"| result="+result);
                    }else if( i == 1){
                        result = result + key + ",";
                        //logger.debug("i=1 | key="+key+"| result="+result);
                        result = result + getKeys(new JSONObject(value));
                    }else if( i == 2){
                        result = result + key + ",";
                        //logger.debug("i=2 | key="+key+"| result="+result);
                        JSONArray arrays = new JSONArray(value);
                        for(int k =0;k<arrays.length();k++){
                            JSONObject array = new JSONObject(arrays.get(k));
                            result = result + getKeys(array) + ",";
                        }
                    }
                }
            }catch(JSONException e){
                e.printStackTrace();
            }
        }
        return result;
    }

    public int testIsArrayORObject(String sJSON){
	/*
	* return 0:既不是array也不是object
	* return 1：是object
	* return 2 ：是Array
	*/
        try {
            JSONArray array = new JSONArray(sJSON);
            return 2;
        } catch (JSONException e) {// 抛错 说明JSON字符不是数组或根本就不是JSON
            try {
                JSONObject object = new JSONObject(sJSON);
                return 1;
            } catch (JSONException e2) {// 抛错 说明JSON字符根本就不是JSON
                //logger.debug("非法的JSON字符串");
                return 0;
            }
        }
    }
}
